class BaseConfig(dict):

    def keys(self):
        return self.__dict__()

    def __dict__(self):
        return {k for k in dir(self) if not k.startswith('__') and not callable(getattr(self, k))}

    def __getitem__(self, item):
        return getattr(self, item)

    def __setitem__(self, key, value):
        setattr(self, key, value)

    def __repr__(self):
        return self.__str__()

    def __iter__(self):
        for key in dir(self):
            if not key.startswith('__') and not callable(getattr(self, key)):
                yield key, getattr(self, key)

    def __str__(self):
        # This will combine the dict representation with the class's own attributes
        class_attrs = {k: getattr(self, k) for k in dir(self) if
                       not k.startswith('__') and not callable(getattr(self, k))}
        all_attrs = {**self, **class_attrs}
        return str(all_attrs)

    def pop(self, k, d=None):
        v = self[k]
        delattr(self, k)
        return k, v


class DummyConfig(dict):
    def __init__(self, **kwargs):
        super().__init__()
        for k, v in kwargs.items():
            setattr(self, k, v)
